#include "ftpmodel.h"
#include <QDebug>
#include <QStringList>
#include <QTemporaryFile>
#include <QFileInfo>
#include <QDesktopServices>
#include <QDir>
#include "common.h"

FtpModel::FtpModel(QObject *parent) :
    QAbstractListModel(parent)
{
    mFtp = new QFtp();

    mLoading = false;
    mCurrentPath = "HOME";
    mConnectionName = "Not connected";
    mProgress = 0;
    mMessage = "no current jobs";


    mDownloadId = -1;
    mUploadId = -1;

    QHash<int, QByteArray> roles;
    roles[nameRole] = "name";
    roles[isDirRole] = "isDir";
    roles[isFileRole] = "isFile";
    roles[sizeRole] = "size";
    roles[lastModifiedRole] = "lastModified";
    setRoleNames(roles);

    connect(mFtp,SIGNAL(stateChanged(int)),this,SLOT(showState(int)));
    connect(mFtp,SIGNAL(done(bool)),this,SLOT(done(bool)));
    connect(mFtp,SIGNAL(listInfo(QUrlInfo)),this,SLOT(addFile(QUrlInfo)));
    connect(mFtp,SIGNAL(rawCommandReply(int,QString)),this,SLOT(rawCommandReply(int,QString)));
    connect(mFtp,SIGNAL(dataTransferProgress(qint64,qint64)),this,SLOT(dataTransferProgress(qint64,qint64)));
    connect(mFtp,SIGNAL(commandFinished(int,bool)),this,SLOT(commandFinished(int,bool)));

    //verifie si le dossier de reception existe! Sinon on le cr�e

    mDestDir = QDesktopServices::storageLocation(QDesktopServices::HomeLocation);
    QDir dir;
#if defined(Q_OS_SYMBIAN)
    if (dir.mkdir("E:/toadftp"))
        mDestDir = dir.absolutePath();

#endif
    qDebug()<<"destDir"<<mDestDir;
}
FtpModel::~FtpModel()
{
    delete mFtp;
    mDownloadFiles.clear();
    mUploadFiles.clear();
    mFilesList.clear();
}
//------------------------------------------------------
int FtpModel::rowCount(const QModelIndex &parent) const
{
    return mFilesList.count();
}
//------------------------------------------------------
QVariant FtpModel::data(const QModelIndex &index, int role) const
{
    if ( index.row() >= mFilesList.count())
        return QVariant();

    if ( role == nameRole)
        return mFilesList[index.row()].name();

    if ( role == isDirRole)
        return mFilesList[index.row()].isDir();

    if ( role == isFileRole)
        return mFilesList[index.row()].isFile();

    if ( role == sizeRole){
        return Common::sizeToString(mFilesList[index.row()].size());
    }

    if ( role == lastModifiedRole)
        return mFilesList[index.row()].lastModified();

    if ( role == Qt::DisplayRole)
        return mFilesList[index.row()].name();

    if ( role == Qt::TextColorRole)
    {
        if ( mFilesList[index.row()].isDir())
            return Qt::red;
        return Qt::white;
    }
    return QVariant();
}
//------------------------------------------------------
void FtpModel::showState(int state)
{
    switch (state)
    {
    case QFtp::Unconnected: mMessage = "unconnected";break;
    case QFtp::HostLookup : mMessage = "Host Lookup...";break;
    case QFtp::Connecting : mMessage = "connecting...";break;
    case QFtp::Connected  : mMessage = "connected";break;
    case QFtp::LoggedIn   : mMessage = "loggedIn";break;
    case QFtp::Closing   : mMessage = "closing"; ;break;
    }

    qDebug()<<mMessage;
    emit messageChanged();
    emit stateChanged();

        if ( state == QFtp::LoggedIn)
            refresh();
}
//------------------------------------------------------
void FtpModel::done(bool error)
{
    // mLoading = false;
    qDebug()<<"done";

    //    emit loadingChanged();

    //    if ( error)
    //    {
    //        qDebug()<<mMessage;
    //        mMessage = mFtp->errorString();
    //        emit messageChanged();
    //    }
}
//------------------------------------------------------
void FtpModel::connectToHost(const QString &host, quint16 port)
{

    qDebug()<<"Connect to "<<host<<":"<<port;
    mConnectionName = host+":"+QString::number(port);
    mFtp->connectToHost(host,port);
    // emit connectionNameChanged();
}
//------------------------------------------------------
void FtpModel::login(const QString &user, const QString &password)
{
    qDebug()<<"Login with "<<user<<":"<<password;
    mFtp->login(user,password);
}
//------------------------------------------------------
void FtpModel::refresh(const QString &dir)
{
    mFilesList.clear();
    mFtp->list(dir);
    mFtp->rawCommand("PWD");
    //emit reset();  // Pas sur qu'on doit le mettre la
}
//------------------------------------------------------
void FtpModel::addFile(const QUrlInfo &i)
{
    beginInsertRows(QModelIndex(),mFilesList.count(), mFilesList.count());
    mFilesList.append(i);
    endInsertRows();

}
//------------------------------------------------------
void FtpModel::openFolder(int index)
{
    if (mFilesList[index].isDir())
        mFtp->cd(mFilesList[index].name());

}
//------------------------------------------------------
void FtpModel::back()
{
    mFtp->cd("..");
}
//------------------------------------------------------
void FtpModel::rawCommandReply(int replyCode, const QString &detail)
{
    Q_UNUSED(replyCode)
    qDebug()<<"raw reply";
    QStringList list = detail.split(" ");
    setCurrentPath(list.first().replace("\"",""));
    emit currentPathChanged();
}
//------------------------------------------------------
void FtpModel::removeFile(int index)
{
    if (mFilesList[index].isDir())
        mFtp->rmdir(mFilesList[index].name());


    if (mFilesList[index].isFile())
        mFtp->remove(mFilesList[index].name());

}
//------------------------------------------------------
void FtpModel::mkdir(const QString& dir)
{
    mFtp->mkdir(dir);
}
//------------------------------------------------------
void FtpModel::dataTransferProgress(qint64 byte, qint64 total)
{
    if (total <= 0)
        return;

    float percent = float(byte)/float(total);
    percent = float(qRound(percent * 100)) / 100;
    mProgress = percent;

    if (mFtp->currentCommand() == QFtp::Get){
        QString name = QFileInfo(*mDownloadFiles.first()).baseName();
        name.truncate(10);
        mMessage = "DL "+name+"... "+QString::number(int(percent*100)) + "%";

    }
    if (mFtp->currentCommand() == QFtp::Put){
        QString name = QFileInfo(*mUploadFiles.first()).baseName();
        name.truncate(10);
        mMessage = "UP "+name+"... "+QString::number(int(percent*100)) + "%";

    }
    emit progressChanged();
    emit messageChanged();
}
//------------------------------------------------------
void FtpModel::downloadFile(int index, const QString &dest)
{
    if (mFilesList[index].isFile())
    {
        QString fileName = mFilesList[index].name();
        QString newFile ;

        if (dest.isEmpty() )
            newFile = mDestDir+QDir::separator()+fileName;
        else
            newFile = dest+QDir::separator()+fileName;

        QFile* file = new QFile(newFile);
        if (!file->open(QIODevice::WriteOnly)) {
            qDebug()<<"cannot create file";
            delete file;
            return;
        }
        mDownloadFiles.append(file);
        emit taskCountChanged();
        mDownloadId = mFtp->get(mFilesList[index].name(), file);
    }
}
//------------------------------------------------------
void FtpModel::uploadFile(const QString &path)
{
    QFileInfo * i = new QFileInfo(path);
    QFile * file = new QFile(path);

    if (!file->open(QIODevice::ReadOnly)) {
        qDebug()<<"cannot read file";
        delete file;
        return;
    }

    mUploadFiles.append(file);
    emit taskCountChanged();
    mUploadId = mFtp->put(file,i->fileName());

}
//------------------------------------------------------
void FtpModel::commandFinished(int id, bool error)
{

    qDebug()<<"commande finished.."<<mFtp->currentCommand();

    if ( error)
    {
        mMessage=mFtp->errorString();
        emit messageChanged();
    }


    if ( mFtp->currentCommand() == QFtp::Cd)
    {
        qDebug()<<"list";
        refresh();

    }

    if (mFtp->currentCommand() == QFtp::Get)
    {
        mMessage="no current jobs";
        qDebug()<<mMessage;
        mDownloadFiles.first()->close();
        mDownloadFiles.removeFirst();
        emit messageChanged();
        emit taskCountChanged();
    }

    if ( mFtp->currentCommand() == QFtp::Put)
    {
        mMessage="no current jobs";
        qDebug()<<mMessage;
        mUploadFiles.first()->close();
        mUploadFiles.removeFirst();
        emit messageChanged();
        emit taskCountChanged();


        if ( mUploadFiles.count() <= 0)
            refresh();
    }

    if ( mFtp->currentCommand() == QFtp::Mkdir)
    {
        refresh();
    }

    if ( (mFtp->currentCommand() == QFtp::Rmdir) || (mFtp->currentCommand() == QFtp::Remove))
    {
        refresh();
    }
    if ( mFtp->currentCommand() == QFtp::Rename)
    {
        refresh();
    }
    //    if ( mFtp->currentCommand() == QFtp::List)
    //    {
    //        emit reset();
    //    }

    if ( mFtp->currentCommand() == QFtp::Close)
    {
        qDebug()<<"close";
        mUploadFiles.clear();
        mDownloadFiles.clear();
        mFilesList.clear();
        mProgress = 0;
        emit progressChanged();
        emit taskCountChanged();
    }

}
//------------------------------------------------------
void FtpModel::close()
{
    mFtp->abort();
    mFtp->close();

    mConnectionName = "No Connection";
    emit connectionNameChanged();
    emit taskCountChanged();
}
//------------------------------------------------------
void FtpModel::clear()
{
    beginRemoveRows(QModelIndex(),0,mFilesList.count());
    mFilesList.clear();
    endRemoveRows();
}
//========================================================
int FtpModel::taskCount()
{
    return mUploadFiles.count() + mDownloadFiles.count();
}
//=========================================================
void FtpModel::renameFile(int index, const QString &name)
{
    QString oldName = mFilesList[index].name();
    mFtp->rename(oldName, name);
}
//=========================================================
QString FtpModel::stateName(int state)
{
    QString name = "unconnected";
    switch (state)
    {
    case QFtp::Unconnected: name = "unconnected";break;
    case QFtp::HostLookup : name = "Host Lookup...";break;
    case QFtp::Connecting : name = "connecting...";break;
    case QFtp::Connected  : name = "connected";break;
    case QFtp::LoggedIn   : name = "loggedIn";break;
    case QFtp::Closing   : name = "closing"; ;break;
    }

    return name;
}
//------------------------------------------------------





